Tarea 5. Detección de Colisiones

Oliver Fernando Cuate González

ocuate@computacion.cs.cinvestav.mx

19 de Noviembre de 2013


Problema


Marco Teórico

Detección de Colisiones: Busca determinar si los objetos dentro del Mundo Virtual estan en contacto entre ellos. Debido a la diversidad de formas entre los objetos que pueden dibuarse, se utilizan algunas técnicas que buscan simplificar este problema y optimizar los cálculos empleados para determinar si existe colisión entre dos objetos.

Estas técnicas se basan en la idea de envolver los objetos dentro de volúmenes para los que sea fácil calcular las colisiones, si hay colisiión entre estos volumenes entonces se puede ir detallando gradualmente el nivel de las colisiones, en caso contrario no es necesario hacer ningún cálculo más.

Las colisiones que se considerarán en este trabajo se discutieron en clase y son las siguientes:

Dispositivo Patriot: Este dispositivo cuenta con seis grados de libertad, es decir, proporciona información sobre su posición bajo seis parámmetros significativos distintos.

El dispositivo cuenta con una pequeña base cuadrada. En esta base se encuentra el origen de su sistema coordenado, es decir, la información que arroja el dispositivo es en base a la ubicación de esta base.

También cuenta con una pequeña pluma con un botón. La posición de la pluma respecto a la base cuadrada y su inclinación son los datos que nos arroja el dispositivo: su posición en x,y,z, así como los cosenos directores de la inclinación de la pluma con cada eje. El botón tiene los estados encendido y apagado (1 y 0).

Según el manual, se puede especificar el formato de salida de los datos, así como las unidades deseadas. Se trabajará con el parámetro "P" que devuelve los datos en formato simple.


Análisis

Se desea que un volúmen envolvente, tenga las siguientes propiedades: Las primitivas empleadas para la construcción del cuadricóptero buscan tener estas propiedades. El mundo es un conjunto de cajas y el cuadricóptero es una combinación de cilindros, una esfera y cuadriláteros para las aspas.

El cuadricóptero puede rotar en todas direcciones, por lo que delimitarlo por una esfera que lo cubra completamente es una buena idea para poder detectar las colisiones de este objeto.

La colisión enttre esferas es más barata, por esta razón las columnas serán encerradas por esferas para verificar una primera colisión Esfera-Esfera, en caso que se cumpla esta colisión se verificará la colisón Caja-Esfera.

Para el uso del dispositivo Patriot se usará un cilindro que indicará la posición y dirección de un rayo. Para saber si el rayo apunta correctamente a la esfera central del cuadricóptero se usará la prueba Esfera-Rayo. En caso de que se detecte una colisión, la esfera del cuadricóptero cambiara de color y hasta ese momento se podrá atrapar con el dispositivo Patriot para que se mueva con él.

Luego de realizar algunas pruebas con el dispositivo, se decidió que el origen del sistema de coordenadas del dispositivo coincidiera con el del mundo virtual una vez que este sea seleccionado. El orden de las coordenadas se cambió ya que el dispositivo retorna los valores de x,y,z; que equivaldrían dentro del mundo virtual a x,z,y, respectivamente. La orientación del cubo del dispositivo debe orientarse correctammente para obtener los movimientos deseados, en caso que la orienntación sea incorrecta, el cuadricóptero se moverá de forma distinta.

Se implementarán métodos para la detección de colisiones antes mencionadas. Los objetos cajas estarán fijos, el cuadricóptero se moverá y su posición será almacenada en todo momento como el centro de su esfera, y finalmente el cilindro que define el rayo rotará pero su punto de referencia se mantendrá fijo.

Cada vez que el cuadricóptero desee cambiar su posición, se verificarán las colisiones, en caso que no exista colisión alguna, el cuadricóptero será dibujado en la nueva posición, pero de haber colisión el cuadricóptero permanecerá en su posición actual.


Alternativa de Solución en Qt y OpenGL

Para el manejo del dispositivo Patriot se usó como base la clase PiTracker.cpp que proporciona varios métodos predeterminados para trabajar con el dispositivo Patriot con una conexión USB. Se creó un objeto ptracker de este tipo para establecer la conexión mediante el comando:

ptracker->UsbConnect( 0x0f44, 0xef12, 0x02, 0x82 );

Una vez establecida la conexión se debe configurar el disporitivo en aspecto como lo son las unidades, el formato de lecture y fijar los puntos de referencia de acuerdo a nuestro mundo virtual. Esto se logra mediante los siguientes comandos:

	/* unidades */
	ptracker->WriteTrkData((void*) "u1\r", 3 );
	/* modo binario */
	ptracker->WriteTrkData((void *) "f1\r", 3 );
	/* fomato de entrada */
	ptracker->WriteTrkData((void *) "o1,2,4,6,10\r", 12 );
	ptracker->WriteTrkData((void *)"\x12\x31\r",3);

	memset(command,0,100);
	ptracker->WriteTrkData((void *)"r1\r",3);
	sprintf(command,"a1,%g,%g,%g,%g,%g,%g,%g,%g,%g\r", 0.0,0.0,0.0,   20.0,0.0,0.0,   0.0,20.0,0.0  );
	ptracker->WriteTrkData( (void *)command, strlen(command) );
		

Una vez que se tiene la conexión se crea un método Patriot() en el que se recuperan los del dispositivo datos mediante los comandos:

ptracker->WriteTrkData( (void *)"p", 1); En donde se especifíca el formato de salida "p".

ptracker->ReadTrkData( (void*)buf, 100); Que retorna los valores y los almacena en un buffer buf defindo previamente.

Se utilzarán los datos de la posición x,y,z; los cosenos directores coon cada eje y el estado del botón (click). El uso de estos datos se especificará más adelante.

Para el manejo de las colisiones se declararon estrcturas que facilitan su implementación, una estructura CAJA con los valores del punto máximo y mínimo de la caja; una estructura ESFERA con el centro y radio; y una estructura RAYO con el punto de referencia del rayo y su vector dirección unitario. El rayo será representado por una línea.

Una vez realzada la conexión con el Patriot, este controla la dirección del cilindro Rayo, la dirección tomada es la que indican los cosenos directores, esta dirección por definición es unitaria. La posición tomada es relativa a la posición en la que se tomó el cuadricóptero por primera vez. Cuando el rayo choca con la esfera del cuadricóptero, esta se pinta de rojo y si se aprieta el botón del dispositivo Patriot, se activa una bandera llamada control que cede el control del cuadricóptero al Patriot. El fragmento de código que hace lo anterior se muestra a continuación:

	click = pFlag[0];

	angsPat[0] = pData[6];  //Coseno director de x
	angsPat[1] = -pData[8]; //Coseno director de y
	angsPat[2] = pData[7];  //Coseno director de z

	if( clAnt==0 && click==1 && colisionEsferaRayo()){
		control = true;
		referencia.x = pData[0];
		referencia.y = -pData[2];
		referencia.z = pData[1];
	}

	if(control){
		posPat[0] = pData[0]-referencia.x;
		posPat[1] = -pData[2]-referencia.y;
		posPat[2] = pData[1]-referencia.z;

        esf_cuad.centro.y = p.y + ( 0.1*posPat[1] - referencia.y );
        esf_cuad.centro.z = p.z + ( 0.1*posPat[2] - referencia.z );*/

        esf_cuad.centro.x = 0.2*posPat[0];
        esf_cuad.centro.y = 0.2*posPat[1] + 10;
        esf_cuad.centro.z = 0.2*posPat[2];

	if(click==0)
		control = false;
	}else{
		rayo.dir.x = angsPat[1];
		rayo.dir.y = angsPat[2];
		rayo.dir.z = angsPat[0];
	}

		

Ahora se verifican las colisiones y si no hay ninguna el cuadricóptero se mueve según los movimientos del Patriot. Se declaran métodos que verifican las colisiones en orden de la manera siguiente:

	if (colisionMundo()){
		esf_cuad.centro = p;
	}else if( colisionConEsfera( & esf_col1)){
		if(colisionCajaEsfera(&col1))
			esf_cuad.centro = p;
	}else if(colisionConEsfera( & esf_col2) )
		if(colisionCajaEsfera(&col2))
			esf_cuad.centro = p;
		

Los controles referidos al manejo del cuadricóptero, la iluminación y la posición de la cámara se mantienen igual que en la tarea anterior.

Estos son los detalles a grandes rasgos de la implementación. Por último se agregan un par de imágenes con diferente perspectiva y el link de descarga del código fuente del programa:

vista1 vista2

vista3 vista3

Descargar Archivo


Bibliografía

Mecate Zambrano Miriam. Interacción con Objetos Deformables. Tesis de maestría, CINVESTAV Departamento de Computación, México, D.F., Noviembre 2008.

Alken, Inc. d/b/a Polhemus. PATRIOT USER MANUAL., Colchester, Vermont, U.S.A., Junio 2012.